﻿using System.Linq;
using CID.Domain.Operations;
using CID.Tests.Support;
using NUnit.Framework;
using Rhino.Mocks;

namespace CID.Domain.Tests.Operations
{
    [TestFixture]
    class LocationTests : BaseFunctionalTests
    {
        private const string Name = "Location Name";
        private const string Description = "Location Description";
        private Location location;

        public override void SetUp()
        {
            base.SetUp();
            location = new Location(Name, Description, StubsBuilder.BuildDeploymentAgentStub());
        }

        #region Constructor
        [Test]
        public void CreateNewLocation()
        {
            var deploymentAgent = StubsBuilder.BuildDeploymentAgentStub();
            var location = new Location(Name, Description, deploymentAgent);

            Assert.AreEqual(Name, location.Name);
            Assert.AreEqual(Description, location.Description);
            deploymentAgent.AssertWasCalled(x => x.AddLocation(location));
            CollectionAssert.IsEmpty(location.Servers);
        }
        #endregion

        #region AddServer
        [Test]
        public void AddServer_ServerWithNoLocationAssigned_ShouldSucceed()
        {
            var server = StubsBuilder.BuildServerStub();

            location.AddServer(server);

            Assert.AreEqual(location, server.Location);
            Assert.AreEqual(1, location.Servers.Count());
            CollectionAssert.Contains(location.Servers, server);
        }

        [Test]
        public void AddServer_ServerWithAnotherLocationAssigned_ShouldSucceed()
        {
            var server = StubsBuilder.BuildServerStub();
            var anotherLocation = StubsBuilder.BuildLocationStub();
            server.Location = anotherLocation;

            location.AddServer(server);

            Assert.AreEqual(location, server.Location);
            Assert.AreEqual(1, location.Servers.Count());
            CollectionAssert.Contains(location.Servers, server);
            anotherLocation.AssertWasCalled(x => x.RemoveServer(server));
        }

        [Test]
        public void AddServerTwice_ServerShouldBeAddedOnlyOnce()
        {
            var server = StubsBuilder.BuildServerStub();

            location.AddServer(server);
            location.AddServer(server);

            Assert.AreEqual(location, server.Location);
            Assert.AreEqual(1, location.Servers.Count());
            CollectionAssert.Contains(location.Servers, server);
        }
        #endregion

        #region RemoveServer
        [Test]
        public void RemoveServer_ServerNotAdded_NothingShouldHappen()
        {
            var server = StubsBuilder.BuildServerStub();

            location.RemoveServer(server);

            Assert.AreEqual(0, location.Servers.Count());
        }

        [Test]
        public void RemoveServer_ServerAlreadyAdded_ShouldSucceed()
        {
            var server = StubsBuilder.BuildServerStub();
            location.AddServer(server);

            location.RemoveServer(server);

            Assert.AreEqual(0, location.Servers.Count());
            Assert.IsNull(server.Location);
        }
        #endregion
    }
}
